<template>
	<view class="calendar-wrapper">
		<view class="header" v-if="headerBar">
			<view class="date-picker"><date-time-picker placeholder="请选择日期" :defaultValue="date" fields="month" @change="timeChange($event, 'date')"></date-time-picker></view>
		</view>

		<view class="week">
			<view class="week-day" v-for="(item, index) in weekDay" :key="index">{{ item }}</view>
		</view>

		<view :class="{ hide: !monthOpen }" class="content" :style="{ height: height }">
			<view :style="{ top: positionTop + 'rpx' }" class="days">
				<view class="item" v-for="(item, index) in dates" :key="index">
					<view
						class="day"
						@click="selectOne(item, $event)"
						:class="{
							choose: choose == `${item.year}-${item.month}-${item.date}` && item.isCurM,
							nolm: !item.isCurM,
							today: isToday(item.year, item.month, item.date),
							isWorkDay: isWorkDay(item.year, item.month, item.date)
						}"
					>
						{{ Number(item.date) }}
						<view class="tag" :class="'mode' + isMarkDay(item.year, item.month, item.date).type" v-if="item.isCurM">
							{{ isMarkDay(item.year, item.month, item.date).typeName }}
						</view>
					</view>
				</view>
			</view>
		</view>
	</view>
</template>

<script>
import dateTimePicker from '@/components/uni-datetime-picker';
export default {
	name: 'ren-calendar',
	components: {
		dateTimePicker
	},
	props: {
		weekstart: {
			type: Number,
			default: 0
		},
		markDays: {
			type: Array,
			default: () => {
				return [];
			}
		},
		headerBar: {
			type: Boolean,
			default: true
		},
		disabledAfter: {
			type: Boolean,
			default: true
		},
		showdownValue: {
			type: String,
			default: '1'
		}
	},
	data() {
		return {
			weektext: ['日', '一', '二', '三', '四', '五', '六'],
			y: new Date().getFullYear(),
			m: new Date().getMonth() + 1,
			date: '',
			dates: [],
			positionTop: 0,
			monthOpen: true,
			choose: ''
		};
	},
	created() {
		this.dates = this.monthDay(this.y, this.m);
		let date = this.$writeCurrentDate();
		this.date = date.year + '-' + date.month + '-' + date.date;
	},
	mounted() {
		this.choose = this.getToday().date;
	},
	computed: {
		weekDay() {
			return this.weektext.slice(this.weekstart).concat(this.weektext.slice(0, this.weekstart));
		},
		height() {
			return (this.dates.length / 7) * 118 + 'rpx';
		}
	},
	methods: {
		formatNum(num) {
			let res = Number(num);
			return res < 10 ? '0' + res : res;
		},
		getToday() {
			let date = new Date();
			let y = date.getFullYear();
			let m = date.getMonth();
			let d = date.getDate();
			let week = new Date().getDay();
			let weekText = ['日', '一', '二', '三', '四', '五', '六'];
			let formatWeek = '星期' + weekText[week];
			let today = {
				date: y + '-' + this.formatNum(m + 1) + '-' + this.formatNum(d),
				week: formatWeek
			};
			return today;
		},
		monthDay(y, month) {
			let dates = [];
			let m = Number(month);
			let firstDayOfMonth = new Date(y, m - 1, 1).getDay();
			let lastDateOfMonth = new Date(y, m, 0).getDate();
			let lastDayOfLastMonth = new Date(y, m - 2, 0).getDate();
			let weekstart = this.weekstart == 7 ? 0 : this.weekstart;
			let startDay = (() => {
				if (firstDayOfMonth == weekstart) {
					return 0;
				} else if (firstDayOfMonth > weekstart) {
					return firstDayOfMonth - weekstart;
				} else {
					return 7 - weekstart + firstDayOfMonth;
				}
			})();
			let endDay = 7 - ((startDay + lastDateOfMonth) % 7);
			for (let i = 1; i <= startDay; i++) {
				dates.push({
					date: this.formatNum(lastDayOfLastMonth - startDay + i),
					day: weekstart + i - 1 || 7,
					month: m - 1 >= 0 ? this.formatNum(m - 1) : 12,
					year: m - 1 >= 0 ? y : y - 1
				});
			}
			for (let j = 1; j <= lastDateOfMonth; j++) {
				dates.push({
					date: this.formatNum(j),
					day: (j % 7) + firstDayOfMonth - 1 || 7,
					month: this.formatNum(m),
					year: y,
					isCurM: true
				});
			}
			for (let k = 1; k <= endDay; k++) {
				dates.push({
					date: this.formatNum(k),
					day: (lastDateOfMonth + startDay + weekstart + k - 1) % 7 || 7,
					month: m + 1 <= 11 ? this.formatNum(m + 1) : 0,
					year: m + 1 <= 11 ? y : y + 1
				});
			}
			return dates;
		},
		isWorkDay(y, m, d) {
			let ymd = `${y}/${m}/${d}`;
			let formatDY = new Date(ymd.replace(/-/g, '/'));
			let week = formatDY.getDay();
			if (week == 0 || week == 6) {
				return false;
			} else {
				return true;
			}
		},
		isFutureDay(y, m, d) {
			let ymd = `${y}/${m}/${d}`;
			let formatDY = new Date(ymd.replace(/-/g, '/'));
			let showTime = formatDY.getTime();
			let curTime = new Date().getTime();
			if (showTime > curTime) {
				return true;
			} else {
				return false;
			}
		},
		isMarkDay(y, m, d) {
			let typeName = '';
			let type = '';
			let dy = `${y}-${m}-${d}`;
			this.markDays.some(item => {
				if (item.days == dy) {
					type = item.type;
					typeName = item.typeName;
				}
			});
			return {
				typeName: typeName,
				type: type
			};
		},
		isToday(y, m, d) {
			let checkD = y + '-' + m + '-' + d;
			let today = this.getToday().date;
			if (checkD == today) {
				return true;
			} else {
				return false;
			}
		},
		selectOne(i, event) {
			let date = `${i.year}-${i.month}-${i.date}`;
			let selectD = new Date(date).getTime();
			let curTime = new Date().getTime();
			let week = new Date(date).getDay();
			let weekText = ['日', '一', '二', '三', '四', '五', '六'];
			let formatWeek = '星期' + weekText[week];
			let response = {
				date: date,
				week: formatWeek
			};
			if (!i.isCurM) {
				this.$msg('不在当前月范围内');
				return false;
			}
			if (selectD > curTime) {
				if (this.disabledAfter) {
					this.$msg('未来日期不可选');
					return false;
				} else {
					this.choose = date;
					this.$emit('onDayClick', response);
				}
			} else {
				this.choose = date;
				this.$emit('onDayClick', response);
			}
		},
		timeChange({ date, dt }, idx) {
			this[idx] = date.year + '-' + date.month2;
			this.y = date.year;
			this.m = date.month2;
			this.dates = this.monthDay(this.y, this.m);
			this.$emit('getYM', this.y + '-' + (this.m > 9 ? this.m : '0' + this.m));
		},
		changYearMonth(y, m) {
			this.dates = this.monthDay(y, m);
			this.y = y;
			this.m = m;
		},
		changeMonth(type) {
			if (type == 'pre') {
				if (this.m + 1 == 2) {
					this.m = 12;
					this.y = this.y - 1;
				} else {
					this.m = this.m - 1;
				}
			} else {
				if (this.m + 1 == 13) {
					this.m = 1;
					this.y = this.y + 1;
				} else {
					this.m = this.m + 1;
				}
			}
			this.dates = this.monthDay(this.y, this.m);
			this.$emit('getYM', this.y + '-' + (this.m > 9 ? this.m : '0' + this.m));
		}
	}
};
</script>

<style lang="scss">
.calendar-wrapper {
	color: #666;
	font-size: 16px;
	text-align: center;
	background-color: #fff;
	padding-bottom: 10rpx;
	border-radius: 20rpx;

	.header {
		display: flex;
		align-items: center;
		justify-content: flex-end;
		margin-bottom: 36rpx;
		color: #42464a;
		font-size: 16px;
	}

	.week {
		display: flex;
		align-items: center;
		font-weight: bold;
		height: 80rpx;
		line-height: 80rpx;
		border-bottom: 1rpx solid rgba(255, 255, 255, 0.2);

		view {
			flex: 1;
		}
	}

	.content {
		position: relative;
		overflow: hidden;
		transition: height 0.4s ease;

		.days {
			transition: top 0.3s;
			display: flex;
			align-items: center;
			flex-wrap: wrap;
			position: relative;

			.item {
				position: relative;
				display: block;
				height: 118rpx;
				line-height: 42rpx;
				width: calc(100% / 7);

				.day {
					margin: 0 auto;
					font-weight: bold;
					padding-top: 8rpx;
					width: 80rpx;
					height: 92rpx;
					font-size: 15px;
					color: #333;
					line-height: 40rpx;
					overflow: hidden;
					border-radius: 6rpx;

					.tag {
						font-size: 10px;
						font-weight: normal;
						color: #666;
					}

					.mode0 {
						color: #666;
					}

					.mode1 {
						color: #ff7100;
					}

					.mode2 {
						color: #ff7100;
					}

					.mode3 {
						color: #ff7100;
					}

					.mode4 {
						color: #3396fb;
					}

					.mode5 {
						color: #49d34e;
					}

					.mode6 {
						color: #f5a623;
					}

					.mode7 {
						color: #2bba91;
					}

					&.choose {
						background-color: #d0021b;
						color: #fff;

						.tag {
							color: #fff;
						}
					}

					&.nolm {
						color: #fff;
						opacity: 0.3;

						.tag {
							color: #fff;
						}
					}
				}
				.isWorkDay {
					color: #42464a;
				}

				.notSigned {
					font-style: normal;
					width: 8rpx;
					height: 8rpx;
					background: #fa7268;
					border-radius: 10rpx;
					position: absolute;
					left: 50%;
					bottom: 0;
					pointer-events: none;
				}

				.today {
					color: #d0021b;
					background-color: #ffdee2;

					.tag {
						color: #d0021b;
					}
				}

				.workDay {
					font-weight: bold;
					width: 8rpx;
					height: 8rpx;
					background: #4d7df9;
					border-radius: 10rpx;
					position: absolute;
					left: 50%;
					bottom: 10rpx;
					pointer-events: none;
				}

				.markDay {
					margin-left: -4rpx;
					font-weight: bold;
					width: 8rpx;
					height: 8rpx;
					background: #fc7a64;
					border-radius: 10rpx;
					position: absolute;
					left: 50%;
					bottom: 10rpx;
					pointer-events: none;
				}
			}
		}
	}

	.hide {
		height: 80rpx !important;
	}
}

.date-picker {
	margin-left: auto;
	padding: 0 10px;
	width: 126px;
	height: 88rpx;
	font-size: 14px;
	color: #afb0b3;
	line-height: 84rpx;
	border-radius: 8rpx;
	border: 1rpx solid;

	/deep/ .flex {
		justify-content: center;
	}
}
</style>
